home *** CD-ROM | disk | FTP | other *** search
/ Total Network Tools 2002 / NextStepPublishing-TotalNetworkTools2002-Win95.iso / Archive / Misc Servers / Zope.exe / EXTENSIONCLASS.STX < prev    next >
Encoding:
Text File  |  1999-03-23  |  30.1 KB  |  715 lines

  1. Extension Classes, Python Extension Types Become Classes
  2.  
  3.   Jim Fulton, Digital Creations, Inc.
  4.   jim@digicool.com
  5.  
  6.   "Copyright (C) 1996-1998, Digital Creations":COPYRIGHT.html.
  7.  
  8.   Abstract
  9.   
  10.     A lightweight mechanism has been developed for making Python
  11.     extension types more class-like.  Classes can be developed in an
  12.     extension language, such as C or C++, and these classes can be
  13.     treated like other python classes:
  14.   
  15.     - They can be sub-classed in python,
  16.   
  17.     - They provide access to method documentation strings, and
  18.   
  19.     - They can be used to directly create new instances.
  20.   
  21.     An example class shows how extension classes are implemented and how
  22.     they differ from extension types.
  23.   
  24.     Extension classes provide additional extensions to class and
  25.     instance semantics, including:
  26.  
  27.     - A protocol for accessing subobjects "in the context of" their
  28.       containers.  This is used to implement custom method types
  29.       and "environmental acquisition":Acquisition.html.
  30.  
  31.     - A protocol for overriding method call semantics.  This is used
  32.       to implement "synchonized" classes and could be used to
  33.       implement argument type checking.
  34.  
  35.     - A protocol for class initialization that supports execution of a
  36.       special '__class_init__' method after a class has been
  37.       initialized. 
  38.   
  39.     Extension classes illustrate how the Python class mechanism can be
  40.     extended and may provide a basis for improved or specialized class
  41.     models. 
  42.  
  43.   Releases
  44.  
  45.     To find out what's changed in this release,
  46.     see the "release notes":release.html.
  47.   
  48.   Problem
  49.   
  50.     Currently, Python provides two ways of defining new kinds of objects:
  51.   
  52.     - Python classes
  53.   
  54.     - Extension types
  55.   
  56.     Each approach has it's strengths.  Extension types provide much greater
  57.     control to the programmer and, generally, better performance.  Because
  58.     extension types are written in C, the programmer has greater access to 
  59.     external resources. (Note that Python's use of the term type has
  60.     little to do with the notion of type as a formal specification.)
  61.   
  62.     Classes provide a higher level of abstraction and are generally much
  63.     easier to develop.  Classes provide full inheritance support, while
  64.     support for inheritance when developing extension types is very
  65.     limited. Classes provide run-time meta-data, such as method documentation
  66.     strings, that are useful for documentation and discovery.  Classes
  67.     act as factories for creating instances, while separate functions
  68.     must be provided to create instances of types.
  69.   
  70.     It would be useful to combine the features of the two approaches.  It 
  71.     would be useful to be able to have better support for inheritance for
  72.     types, or to be able to subclass from types in Python.  It would be
  73.     useful to be able to have class-like meta-data support for types and
  74.     the ability to construct instances directly from types.
  75.  
  76.     Our software is developed in Python.  When necessary, we convert
  77.     debugged Python routines and classes to C for improved
  78.     performance.  In most cases, a small number of methods in a class
  79.     is responsible for most of the computation.  It should be possible
  80.     to convert only these methods to C, while leaving the other method
  81.     in Python.  A natural way to approach this is to create a base
  82.     class in C that contains only the performance-critical aspects of
  83.     a class' implementation and mix this base class into a Python
  84.     class. 
  85.  
  86.     We have need, in a number of projects, for semantics that are
  87.     slightly different than the usual class and instance semantics,
  88.     yet we don't want to do most of our development in C.  For
  89.     example, we have developed a persistence mechanism [1] that
  90.     redefines '__getattr__' and '__setattr__' to take storage-related
  91.     actions when object state is accessed or modified.  We want to be
  92.     able to take certain actions on *every* attribute reference, but
  93.     for python class instances, '__getattr__' is only called when
  94.     attribute lookup fails by normal means.
  95.  
  96.     As another example, we would like to have greater control over how
  97.     methods are bound.  Currently, when accessing a class
  98.     instance attribute, the attribute value is bound together with the
  99.     instance in a method object *if and only if* the attribute value is a
  100.     python function.  For some applications, we might also want to be
  101.     able to bind extension functions, or other types of callable
  102.     objects, such as HTML document templates [2]. Furthermore,
  103.     we might want to have greater control over how objects are bound.
  104.     For example, we might want to bind instances and callable objects
  105.     with special method objects that assure that no more than one thread
  106.     accesses the object or method at one time.
  107.   
  108.     We can provide these special semantics in extension types, but we
  109.     wish to provide them for classes developed in Python.
  110.   
  111.   Background
  112.   
  113.     At the first Python Workshop, Don Beaudry presented work [3] done
  114.     at V.I. Corp to integrate Python with C++ frameworks.  This system
  115.     provided a number of important features, including:
  116.   
  117.     - Definition of extension types that provide class-like meta-data
  118.       and that can be called to create instances.
  119.   
  120.     - Ability to subclass in python from C types.
  121.   
  122.     - Ability to define classes in python who's data are stored as
  123.       C structures rather than in dictionaries to better interface to
  124.       C and C++ libraries, and for better performance.
  125.   
  126.     - Less dynamic data structures.  In particular, the data structure
  127.       for a class is declared during class definition.
  128.   
  129.     - Support for enumeration types.
  130.   
  131.     This work was not released, initially.
  132.   
  133.     Shortly after the workshop, changes were made to Python to support
  134.     the sub-classing features described in [3].  These changes were not
  135.     documented until the fourth Python Workshop [4].
  136.   
  137.     At the third Python workshop, I presented some work I had done on
  138.     generating module documentation for extension types.  Based on the
  139.     discussion at this workshop, I developed a meta-type proposal [5].
  140.     This meta-type proposal was for an object that simply stored
  141.     meta-information for a type, for the purpose of generating module
  142.     documentation.
  143.   
  144.     In the summer of 1996, Don Beaudry released the system described in
  145.     [3] under the name MESS [6]. MESS addresses a number of needs but
  146.     has a few drawbacks:
  147.   
  148.     - Only single inheritance is supported.
  149.   
  150.     - The mechanisms for defining MESS extension types is very different
  151.       from and more complicated than the standard Python type creation
  152.       mechanism.
  153.   
  154.     - Defining MESS types requires the use of an extensive C
  155.       applications programming interface.  This presents problems for
  156.       configuring dynamically-loaded extension modules unless the MESS
  157.       library is linked into the Python interpreter.
  158.   
  159.     - Because the system tries to do a number of different things, it is
  160.       fairly large, about 15,000 lines.
  161.   
  162.     - There is very little documentation, especially for the C
  163.       programming interface.
  164.   
  165.     - The system is a work in progress, with a number of outstanding
  166.       bugs.
  167.   
  168.     As MESS matures, we expect most of these problems to be addressed.
  169.   
  170.   Extension Classes
  171.   
  172.     To meet short term needs for a C-based persistence mechanism [1], an
  173.     extension class module was developed using the mechanism described
  174.     in [4] and building on ideas from MESS [6].  The extension class module
  175.     recasts extension types as "extension classes" by seeking to
  176.     eliminate, or at least reduce semantic differences between types and
  177.     classes. The module was designed to meet the following goal:
  178.   
  179.     - Provide class-like behavior for extension types, including
  180.       interfaces for meta information and for constructing instances.
  181.   
  182.     - Support sub-classing in Python from extension classes, with support
  183.       for multiple inheritance.
  184.   
  185.     - Provide a small hardened implementation that can be used for
  186.       current products.
  187.   
  188.     - Provide a mechanism that requires minimal modification to existing
  189.       extension types.
  190.   
  191.     - Provide a basis for research on alternative semantics for classes
  192.       and inheritance.
  193.  
  194.     **Note:** I use *non-standard* terminology here.  By standard
  195.     *python* terminology, only standard python classes can be called
  196.     classes.  ExtensionClass "classes" are technically just "types"
  197.     that happen to swim, walk and quack like python classes.
  198.    
  199.     Base extension classes and extension subclasses
  200.   
  201.       Base extension classes are implemented in C.  Extension subclasses
  202.       are implemented in Python and inherit, directly or indirectly from
  203.       one or more base extension classes.  An extension subclass may
  204.       inherit from base extension classes, extension subclasses, and
  205.       ordinary python classes.  The usual inheritance order rules
  206.       apply.  Currently, extension subclasses must conform to the
  207.       following two rules:
  208.   
  209.       - The first super class listed in the class statement defining an
  210.     extension subclass must be either a base extension class or an
  211.     extension subclass.  This restriction will be removed in
  212.     Python-1.5.
  213.   
  214.       - At most one base extension direct or indirect super class may
  215.     define C data members.  If an extension subclass inherits from
  216.     multiple base extension classes, then all but one must be mix-in
  217.     classes that provide extension methods but no data.
  218.   
  219.     Meta Information
  220.   
  221.       Like standard python classes, extension classes have the following
  222.       attributes containing meta-data:
  223.   
  224.       '__doc__'   -- a documentation string for the class,
  225.            
  226.       '__name__'  -- the class name,
  227.            
  228.       '__bases__' -- a sequence of base classes,
  229.            
  230.       '__dict__'  -- a class dictionary, and
  231.  
  232.       '__module__' -- the name of the module in which the class was
  233.                       defined. 
  234.   
  235.       The class dictionary provides access to unbound methods and their
  236.       documentation strings, including extension methods and special
  237.       methods, such as methods that implement sequence and numeric
  238.       protocols.  Unbound methods can be called with instance first
  239.       arguments.
  240.   
  241.     Subclass instance data
  242.   
  243.       Extension subclass instances have instance dictionaries, just
  244.       like Python class instances do.  When fetching attribute values,
  245.       extension class instances will first try to obtain data from the
  246.       base extension class data structure, then from the instance
  247.       dictionary, then from the class dictionary, and finally from base
  248.       classes.  When setting attributes, extension classes first attempt
  249.       to use extension base class attribute setting operations, and if
  250.       these fail, then data are placed in the instance dictionary.
  251.   
  252.   Implementing base extension classes
  253.   
  254.     A base extension class is implemented in much the same way that an
  255.     extension type is implemented, except:
  256.   
  257.     - The include file, 'ExtensionClass.h', must be included.
  258.   
  259.     - The type structure is declared to be of type 'PyExtensionClass', rather 
  260.       than of type 'PyTypeObject'.
  261.   
  262.     - The type structure has an additional member that must be defined
  263.       after the documentation string.  This extra member is a method chain
  264.       ('PyMethodChain') containing a linked list of method definition
  265.       ('PyMethodDef') lists.  Method chains can be used to implement
  266.       method inheritance in C.  Most extensions don't use method chains,
  267.       but simply define method lists, which are null-terminated arrays
  268.       of method definitions.  A macro, 'METHOD_CHAIN' is defined in
  269.       'ExtensionClass.h' that converts a method list to a method chain.
  270.       (See the example below.)
  271.   
  272.     - Module functions that create new instances must be replaced by 
  273.       '__init__' methods that initialize, but does not create storage for 
  274.       instances.
  275.   
  276.     - The extension class must be initialized and exported to the module
  277.       with::
  278.   
  279.       PyExtensionClass_Export(d,"name",type);
  280.   
  281.       where 'name' is the module name and 'type' is the extension class
  282.       type object.
  283.   
  284.     Attribute lookup
  285.   
  286.       Attribute lookup is performed by calling the base extension class
  287.       'getattr' operation for the base extension class that includes C
  288.       data, or for the first base extension class, if none of the base
  289.       extension classes include C data.  'ExtensionClass.h' defines a
  290.       macro 'Py_FindAttrString' that can be used to find an object's
  291.       attributes that are stored in the object's instance dictionary or
  292.       in the object's class or base classes::
  293.   
  294.      v = Py_FindAttrString(self,name);
  295.   
  296.       where 'name' is a C string containing the attribute name.
  297.  
  298.       In addition, a macro is provided that replaces 'Py_FindMethod'
  299.       calls with logic to perform the same sort of lookup that is
  300.       provided by 'Py_FindAttrString'.
  301.  
  302.       If an attribute name is contained in a Python string object,
  303.       rather than a C string object, then the macro 'Py_FindAttr' should
  304.       be used to look up an attribute value.
  305.   
  306.     Linking
  307.   
  308.       The extension class mechanism was designed to be useful with
  309.       dynamically linked extension modules.  Modules that implement
  310.       extension classes do not have to be linked against an extension
  311.       class library.  The macro 'PyExtensionClass_Export' imports the
  312.       'ExtensionClass' module and uses objects imported from this module
  313.       to initialize an extension class with necessary behavior.
  314.   
  315.     Example: MultiMapping objects
  316.  
  317.       An "example":MultiMapping.html, is provided that illustrates the
  318.       changes needed to convert an existing type to an ExtensionClass.
  319.  
  320.   Implementing base extension class constructors
  321.  
  322.     Some care should be taken when implementing or overriding base
  323.     class constructors.  When a Python class overrides a base class
  324.     constructor and fails to call the base class constructor, a
  325.     program using the class may fail, but it will not crash the
  326.     interpreter. On the other hand, an extension subclass that
  327.     overrides a constructor in an extension base class must call the
  328.     extension base class constructor or risk crashing the interpreter.
  329.     This is because the base class constructor may set C pointers that,
  330.     if not set properly, will cause the interpreter to crash when
  331.     accessed.  This is the case with the 'MultiMapping' extension base
  332.     class shown in the example above.
  333.  
  334.     If no base class constructor is provided, extension class instance
  335.     memory will be initialized to 0.  It is a good idea to design
  336.     extension base classes so that instance methods check for
  337.     uninitialized memory and perform initialialization if necessary.
  338.     This was not done above to simplify the example.
  339.  
  340.   Overriding methods inherited from Python base classes
  341.  
  342.     A problem occurs when trying to overide methods inherited from
  343.     Python base classes.  Consider the following example::
  344.  
  345.       from ExtensionClass import Base
  346.  
  347.       class Spam:
  348.  
  349.         def __init__(self, name):
  350.       self.name=name
  351.  
  352.       class ECSpam(Base, Spam):
  353.  
  354.         def __init__(self, name, favorite_color):
  355.       Spam.__init__(self,name)
  356.       self.favorite_color=favorite_color
  357.  
  358.     This implementation will fail when an 'ECSpam' object is
  359.     instantiated.  The problem is that 'ECSpam.__init__' calls
  360.     'Spam.__init__', and 'Spam.__init__' can only be called with a
  361.     Python instance (an object of type '"instance"') as the first
  362.     argument.  The first argument passed to 'Spam.__init__' will be an
  363.     'ECSpam' instance (an object of type 'ECSPam').
  364.  
  365.     To overcome this problem, extension classes provide a class method
  366.     'inheritedAttribute' that can be used to obtain an inherited
  367.     attribute that is suitable for calling with an extension class
  368.     instance.  Using the 'inheritedAttribute' method, the above
  369.     example can be rewritten as::
  370.  
  371.       from ExtensionClass import Base
  372.  
  373.       class Spam:
  374.  
  375.         def __init__(self, name):
  376.       self.name=name
  377.  
  378.       class ECSpam(Base, Spam):
  379.  
  380.         def __init__(self, name, favorite_color):
  381.       ECSpam.inheritedAttribute('__init__')(self,name)
  382.       self.favorite_color=favorite_color
  383.  
  384.     This isn't as pretty but does provide the desired result.
  385.  
  386.   New class and instance semantics
  387.  
  388.     Context Wrapping
  389.  
  390.       It is sometimes useful to be able to wrap up an object together
  391.       with a containing object.  I call this "context wrapping"
  392.       because an object is accessed in the context of the object it is
  393.       accessed through.
  394.  
  395.       We have found many applications for this, including:
  396.  
  397.         - User-defined method objects, 
  398.  
  399.     - "Acquisition":Acquisition.html, and
  400.  
  401.     - Computed attributes
  402.   
  403.       User-defined method objects
  404.       
  405.     Python classes wrap Python function attributes into methods.  When a
  406.     class has a function attribute that is accessed as an instance
  407.     attribute, a method object is created and returned that contains
  408.     references to the original function and instance.  When the method
  409.     is called, the original function is called with the instance as the
  410.     first argument followed by any arguments passed to the method.
  411.     
  412.     Extension classes provide a similar mechanism for attributes that
  413.     are Python functions or inherited extension functions.  In
  414.     addition, if an extension class attribute is an instance of an
  415.     extension class that defines an '__of__' method, then when the
  416.     attribute is accessed through an instance, it's '__of__' method
  417.     will be called to create a bound method.
  418.  
  419.     Consider the following example::
  420.       
  421.       import ExtensionClass
  422.       
  423.       class CustomMethod(ExtensionClass.Base):
  424.       
  425.         def __call__(self,ob): 
  426.               print 'a %s was called' % ob.__class__.__name__
  427.       
  428.         class wrapper:
  429.       
  430.           def __init__(self,m,o): self.meth, self.ob=m,o
  431.       
  432.           def __call__(self): self.meth(self.ob)
  433.       
  434.         def __of__(self,o): return self.wrapper(self,o)
  435.       
  436.       class bar(ExtensionClass.Base):
  437.         hi=CustomMethod()
  438.       
  439.       x=bar()
  440.       hi=x.hi()
  441.       
  442.     Note that 'ExtensionClass.Base' is a base extension class that
  443.     provides very basic ExtensionClass behavior. 
  444.       
  445.     When run, this program outputs: 'a bar was called'.
  446.  
  447.       Computed Attributes
  448.  
  449.     It is not uncommon to wish to expose information via the
  450.     attribute interface without affecting implementation data
  451.     structures.  One can use a custom '__getattr__' method to
  452.     implement computed attributes, however, this can be a bit
  453.     cumbersome and can interfere with other uses of '__getattr__',
  454.     such as for persistence.
  455.  
  456.     The '__of__' protocol provides a convenient way to implement
  457.     computed attributes. First, we define a ComputedAttribute
  458.     class.  a ComputedAttribute is constructed with a function to
  459.     be used to compute an attribute, and calls the function when
  460.     it's '__of__' method is called:
  461.  
  462.       import ExtensionClass
  463.     
  464.       class ComputedAttribute(ExtensionClass.Base):
  465.     
  466.         def __init__(self, func): self.func=func
  467.     
  468.         def __of__(self, parent): return self.func(parent)
  469.     
  470.     Then we can use this class to create computed attributes.  In the
  471.     example below, we create a computed attribute, 'radius':
  472.     
  473.       from math import sqrt
  474.     
  475.       class Point(ExtensionClass.Base):
  476.     
  477.         def __init__(self, x, y): self.x, self.y = x, y
  478.     
  479.         radius=ComputedAttribute(lambda self: sqrt(self.x**2+self.y**2))
  480.     
  481.     which we can use just like an ordinary attribute:
  482.     
  483.       p=Point(2,2)
  484.       print p.radius
  485.  
  486.     Overriding method calls
  487.  
  488.       Normally, when a method is called, the function wrapped by the
  489.       method is called directly by the method.  In some cases, it is
  490.       useful for user-defined logic to participate in the actual
  491.       function call.  Extension classes introduce a new protocol that
  492.       provides extension classes greater control over how their
  493.       methods are called.  If an extension class defines a special
  494.       method, '__call_method__', then this method will be called to
  495.       call the functions (or other callable object) wrapped by the
  496.       method.  The method. '__call_method__' should provide the same
  497.       interface as provided by the Python builtin 'apply' function.
  498.  
  499.       For example, consider the expression: 'x.meth(arg1, arg2)'.  The
  500.       expression is evaluated by first computing a method object that
  501.       wraps 'x' and the attribute of 'x' stored under the name 'meth'.
  502.       Assuming that 'x' has a '__call_method__' method defined, then
  503.       the '__call_method__' method of 'x' will be called with two
  504.       arguments, the attribute of 'x' stored under the name 'meth',
  505.       and a tuple containing 'x', 'arg1', and 'arg2'.
  506.  
  507.       To see how this feature may be used, see the Python module,
  508.       'Syn.py', which is included in the ExtensionClass distribution.
  509.       This module provides a mix-in class that provides Java-like
  510.       "synchonized" classes that limit access to their methods to one
  511.       thread at a time.
  512.  
  513.       An interesting application of this mechanism would be to
  514.       implement interface checking on method calls.
  515.  
  516.     Method attributes
  517.  
  518.       Methods of ExtensionClass instances can have user-defined
  519.       attributes, which are stored in their associated instances.
  520.  
  521.       For example::
  522.  
  523.         class C(ExtensionClass.Base):
  524.  
  525.       def get_secret(self):
  526.         "Get a secret"
  527.         ....
  528.  
  529.     c=C()
  530.  
  531.     c.f.__roles__=['Trusted People']
  532.  
  533.     print c.f.__roles__ # outputs ['Trusted People']
  534.     print c.f__roles__  # outputs ['Trusted People']
  535.  
  536.     print C.f.__roles__ # fails, unbound method
  537.  
  538.       A bound method attribute is set by setting an attribute in it's
  539.       instance with a name consisting of the concatination of the
  540.       method's '__name__' attribute and the attribute name.
  541.       Attributes cannot be set on unbound methods.
  542.  
  543.     Class initialization
  544.  
  545.       Normal Python class initialization is similar to but subtley
  546.       different from instance initialization.  An instance '__init__'
  547.       function is called on an instance immediately *after* it is
  548.       created.  An instance '__init__' function can use instance
  549.       information, like it's class and can pass the instance to other
  550.       functions.  On the other hand, the code in class statements is
  551.       executed immediately *before* the class is created.  This means
  552.       that the code in a class statement cannot use class attributes,
  553.       like '__bases__', or pass the class to functions.
  554.  
  555.       Extension classes provide a mechanism for specifying code to be
  556.       run *after* a class has been created.  If a class or one of it's
  557.       base classes defines a '__class_init__' method, then this method
  558.       will be called just after a class has been created.  The one
  559.       argument passed to the method will be the class, *not* an
  560.       instance of the class.
  561.  
  562.   Useful macros defined in ExtensionClass.h
  563.  
  564.     A number of useful macros are defined in ExtensionClass.h.
  565.     These are documented in 'ExtensionClass.h'.
  566.  
  567.   Pickleability
  568.  
  569.     Classes created with ExtensionClass, including extension base
  570.     classes are automatically pickleable.  The usual gymnastics
  571.     necessary to pickle 'non-standard' types are not necessray for
  572.     types that have been modified to be extension base classes.
  573.  
  574.   Status
  575.  
  576.     The current release of the extension class module is "1.1",
  577.     http://www.digicool.com/releases/ExtensionClass/ExtensionClass-1.1.tar.gz.
  578.     The core implementation has less than four thousand lines of code,
  579.     including comments.  This release requires Python 1.4 or higher.
  580.  
  581.     To find out what's changed in this release, see the
  582.     "release notes":release.html.
  583.  
  584.     "Installation instructions":Installation.html, are provided.
  585.  
  586.   Issues
  587.   
  588.     There are a number of issues that came up in the course of this work
  589.     and that deserve mention.
  590.   
  591.     - In Python 1.4, the class extension mechanism described in [4] required
  592.       that the first superclass in a list of super-classes must be of the
  593.       extended class type.  This may not be convenient if mix-in
  594.       behavior is desired.  If a list of base classes starts with a
  595.       standard python class, but includes an extension class, then an
  596.       error was raised.  It would be more useful if, when a list of base
  597.       classes contains one or more objects that are not python classes,
  598.       the first such object was used to control the extended class
  599.       definition.  To get around this, the 'ExtensionClass' module exports
  600.       a base extension class, 'Base', that can be used as the first base
  601.       class in a list of base classes to assure that an extension
  602.       subclass is created.
  603.  
  604.       Python 1.5 allows the class extension even if the first non-class
  605.       object in the list of base classes is not the first object in
  606.       the list.  This issue appears to go away in Python 1.5, however,
  607.       the restriction that the first non-class object in a list of
  608.       base classes must be the first in the list may reappear in later
  609.       versions of Python.
  610.   
  611.     - Currently, only one base extension class can define any data in
  612.       C.  The data layout of subclasses-instances is the same as for the
  613.       base class that defines data in C, except that the data structure
  614.       is extended to hold an instance dictionary.  The data structure
  615.       begins with a standard python header, and extension methods expect
  616.       the C instance data to occur immediately after the object header.  If
  617.       two or more base classes defined C data, the methods for the
  618.       different base classes would expect their data to be in the same
  619.       location. A solution might be to allocate base class instances and
  620.       store pointers to these instances in the subclass data structure.
  621.       The method binding mechanism would have to be a more complicated
  622.       to make sure that methods were bound to the correct base data
  623.       structure.  Alternatively, the signature of C methods could be
  624.       expanded to allow pointers to expected class data to be passed
  625.       in addition to object pointers.
  626.  
  627.     - There is currently no support for sub-classing in C, beyond that
  628.       provided by method chains.
  629.   
  630.     - Rules for mixed-type arithmetic are different for python class
  631.       instances than they are for extension type instances.  Python
  632.       classes can define right and left versions of numeric binary
  633.       operators, or they can define a coercion operator for converting
  634.       binary operator operands to a common type.  For extension types,
  635.       only the latter, coercion-based, approach is supported.  The
  636.       coercion-based approach does not work well for many data types for
  637.       which coercion rules depend on the operator.  Because extension
  638.       classes are based on extension types, they are currently limited
  639.       to the coercion-based approach.  It should be possible to
  640.       extend the extension class implementation to allow both types of
  641.       mixed-type arithmetic control.
  642.   
  643.     - I considered making extension classes immutable, meaning that
  644.       class attributes could not be set after class creation.  I also
  645.       considered making extension subclasses cache inherited
  646.       attributes.  Both of these are related and attractive for some
  647.       applications, however, I decided that it would be better to retain
  648.       standard class instance semantics and provide these features as
  649.       options at a later time.
  650.   
  651.     - The extension class module defines new method types to bind C and
  652.       python methods to extension class instances.  It would be useful
  653.       for these method objects to provide access to function call
  654.       information, such as the number and names of arguments and the
  655.       number of defaults, by parsing extension function documentation
  656.       strings.
  657.   
  658.   Applications
  659.   
  660.     Aside from test and demonstration applications, the extension class
  661.     mechanism has been used to provide an extension-based implementation
  662.     of the persistence mechanism described in [1].  We have developed
  663.     this further to provide features such as automatic deactivation of
  664.     objects not used after some period of time and to provide more
  665.     efficient persistent-object cache management.
  666.  
  667.     Acquisition has been heavily used in our recent products.
  668.     Synchonized classes have also been used in recent products.
  669.   
  670.   Summary
  671.     
  672.     The extension-class mechanism described here provides a way to add
  673.     class services to extension types.  It allows:
  674.   
  675.       - Sub-classing extension classes in Python,
  676.   
  677.       - Construction of extension class instances by calling extension
  678.     classes,
  679.   
  680.       - Extension classes to provide meta-data, such as unbound methods
  681.     and their documentation string.
  682.   
  683.     In addition, the extension class module provides a relatively
  684.     concise example of the use of mechanisms that were added to Python
  685.     to support MESS [6], and that were described at the fourth Python
  686.     Workshop [4].  It is hoped that this will spur research in improved
  687.     and specialized models for class implementation in Python.
  688.   
  689.   References
  690.   
  691. .. [1] Fulton, J., "Providing Persistence for World-Wide-Web Applications", 
  692.  http://www.digicool.com/papers/Persistence.html,
  693.  Proceedings of the 5th Python Workshop.
  694.    
  695. .. [2] Page, R. and Cropper, S., "Document Template", 
  696.  http://www.digicool.com/papers/DocumentTemplate.html,
  697.  Proceedings of the 5th Python Workshop.
  698.    
  699. .. [3] Beaudry, D., "Deriving Built-In Classes in Python", 
  700.  http://www.python.org/workshops/1994-11/BuiltInClasses/BuiltInClasses_1.html,
  701.  Proceedings of the First International Python Workshop.
  702.    
  703. .. [4] Van Rossum, G., "Don Beaudry Hack - MESS", 
  704.  http://www.python.org/workshops/1996-06/notes/thursday.html,
  705.  presented in the Developer's Future Enhancements session of the 
  706.  4th Python Workshop. 
  707.    
  708. .. [5] Fulton, J., "Meta-Type Object",
  709.  http://www.digicool.com/jim/MetaType.c,
  710.  This is a small proposal, the text of which is contained in a 
  711.  sample implementation source file,  
  712.    
  713. .. [6] Beaudry, D., and Ascher, D., "The Meta-Extension Set", 
  714.  http://starship.skyport.net/~da/mess/.
  715.